#pragma once

#include "task_base.h"
#include "application/vehicle/vehicle_service.h"
#include "application/map/map_application_service.h"
#include "application/dispatcher/dispatcher_service.h"
#include <memory>
#include <string>
#include <chrono>

namespace application {
namespace charge { class ChargePoint; }
namespace task {

/**
 * @brief 充电任务 - AGV前往充电桩充电
 * @details 对应三方代码中的 TaskCharge
 *          使用 VehicleService 进行充电控制
 */
class ChargeTask : public SubTaskBase {
public:
    /**
     * @brief 构造函数
     * @param vehicleService 车辆服务
     * @param logger 日志记录器
     * @param chargePoint 充电点ID（可选，为空则自动选择）
     * @param targetBatteryLevel 目标电量百分比，默认100
     */
    ChargeTask(
        std::shared_ptr<vehicle::VehicleService> vehicleService,
        std::shared_ptr<MapApplicationService> mapService,
        std::shared_ptr<dispatcher::DispatcherService> dispatcherService,
        std::shared_ptr<kernel::ILogger> logger,
        const std::string& chargePoint = "",
        int targetBatteryLevel = 100
    );

    ~ChargeTask() override = default;

    // SubTaskBase 接口实现
    kernel::task::TaskStage init(TaskContext& ctx) override;
    kernel::task::TaskStage run(TaskContext& ctx) override;
    kernel::task::TaskStage cleanup(TaskContext& ctx) override;

    kernel::task::TaskType getType() const override {
        return kernel::task::TaskType::Charge;
    }

    std::string getDescription() const override {
        return "Charge at: " +
               (m_chargePoint.empty() ? "auto" : m_chargePoint);
    }

private:
    // 车辆服务
    std::shared_ptr<vehicle::VehicleService> m_vehicleService;

    // 地图服务
    std::shared_ptr<MapApplicationService> m_mapService;

    // 调度服务
    std::shared_ptr<dispatcher::DispatcherService> m_dispatcherService;

    // 充电点ID
    std::string m_chargePoint;

    // 目标电量百分比
    int m_targetBatteryLevel;

    // 充电命令是否已发送
    bool m_chargingStarted{false};

    // 充电开始时间
    std::chrono::system_clock::time_point m_chargeStartTime;

    // 实际使用的充电点
    std::string m_activeChargePoint;
    std::string m_stationPoint;
    std::string m_actionPoint;
    std::string m_navigationTarget;
    int m_navigationFloor{-1};
    enum class ChargeStrategy { Mklm, Seer };
    enum class SeerPhase { MoveToStation, CloseDo, MoveToAction, WaitCharging };
    ChargeStrategy m_strategy{ChargeStrategy::Mklm};
    bool m_strategyInitialized{false};
    SeerPhase m_seerPhase{SeerPhase::MoveToStation};
    bool m_seerDoorClosed{false};

    /**
     * @brief 检查充电是否超时
     * @return 是否超时
     */
    bool isChargeTimeout() const;

    void enterTimeoutState(TaskContext& ctx, const std::string& message);

    /**
     * @brief 分配或获取已有的充电点
     */
    std::shared_ptr<charge::ChargePoint> ensureChargePoint(TaskContext& ctx);

    /**
     * @brief 获取当前楼层
     */
    int resolveCurrentFloor(const TaskContext& ctx) const;

    void initializeStrategy(const TaskContext& ctx, const std::shared_ptr<charge::ChargePoint>& point);
    kernel::task::TaskStage runMklmStrategy(TaskContext& ctx);
    kernel::task::TaskStage runSeerStrategy(TaskContext& ctx);
    bool isAtStation(const TaskContext& ctx, const std::string& station) const;
    void requestNavigation(TaskContext& ctx, const std::string& station);
    bool sendSeerDockCommand(TaskContext& ctx, bool open);
    bool sendSeerDirectMoveToAction(TaskContext& ctx);

    // 充电超时时间（秒），默认2分钟
    static constexpr int CHARGE_TIMEOUT_SECONDS = 120;
    static constexpr int SEER_CHARGE_DO_CHANNEL = 7;

    bool m_seerActionMoveIssued{false};

public:
    std::string getNavigationTarget() const { return m_navigationTarget; }
    int getNavigationFloor() const { return m_navigationFloor; }
};

} // namespace task
} // namespace application
